
# REST API (CRUD) сервис

RESTful web service представляет данные в удобном для клиента формате с использованием протокола HTTP и принципов REST по модели client <-> server.
<p>В приложении реализовано:

- Создание сущности.
- Обновление сущности.
- Удаление сущности.
- Получение информации о сущности.
- Хранение истории изменений сущности.
- Валидация полей сущности.

<p>
История изменений сущности сохраняется json-поле сущности.
<p>
Доступ в сервису предоставляется по токену.
Работоспособность функционала приложения и БД контролируется тестами, охватывающими 100% используемого кода.

С отчетом о покрытии кода тестами можно ознакомиться: `tests/coverage_report/index.html`.

## Начальная настройка

Создать две базы данных, пустую базу данных для проведения тестов и рабочую. <p>
В `/config/app.ini` записать настройки подключения к базам данных.<p> 
В `/config/apiTokens.php` внести список доступных токенов. <p>
Выполнить в консоле следующие команды:
- `composer install`          - Установить необходимые пакеты.
- `mysql -u db_user -p db_name < schema.sql` - Создать таблицы рабочей БД из файла. db_user и db_name в соответствии с /config/app.ini<p>


## Сущность

<p>Сущность: Item
<p>Поля сущности:

- id - int автоинкремент
- name - char(255)
- phone - char(15)
- key - char(25) not null
- history - json - хранение истории изменения сущности
- created_at - datetime - дата создания сущности
- updated_at - datetime - дата обновления сущности
- deleted_at - datetime - дата удаления сущности

## Добавление элемента

- Авторизация по Bearer Token в заголовке запроса.
- Метод запроса: POST
- URL: /api/item

<p>Параметры:

- name - char(255)
- phone - char(15)
- key - char(25) not null

## Получение информации о элементе

- Авторизация по Bearer Token в заголовке запроса.
- Метод запроса: GET
- URL: /api/item

<p>Параметры:

- id - int(10)

## Изменение элемента

- Авторизация по Bearer Token в заголовке запроса.
- Метод запроса: PUT
- URL: /api/item

<p>Параметры:

- id - int(10) - обязательный
- name - char(255)
- phone - char(15)
- key - char(25) not null

Указываются изменяемые поля.

## Удаление элемента

- Авторизация по Bearer Token в заголовке запроса.
- Метод запроса: DELETE
- URL: /api/item

<p>Параметры:

- id - int(10) - обязательный

## Получаемые данные

<p>
JSON-формат

```
{
    "message": "successful",
    "data": {
        "item": {
            "id": 1,
            "name": "Имя",
            "phone": "телефон",
            "key": "ключ",
            "history": [
                {
                    "key": "ключ",
                    "name": "Имя",
                    "phone": "телефон",
                    "updated_at": "дата и время изменения",
                },
                {
                    "key": "ключ",
                    "name": "Имя",
                    "phone": "телефон",
                    "updated_at": "дата и время изменения",
                }
            ],
            "created_at": "дата и время создания",
            "updated_at": "дата и время изменения"
        }
    }
}
```

<p>
Примечание: <p>
В поле "message" выводится информация об успешности конкретных действий, например: "successful deleted" <p>
При добавлении или обновлении сущности возвращаются сведения, полученные из базы после выполнения операции.<p>
В поле "history" поле "key" выводится первым поскольку при записи в БД поля JSON происходит автоматическая сортировка для повышения эффективности поиска.

## Вывод сведений об ошибках


<p>
JSON-формат

```
{
    "message": "error",
    "reason": "Item not found"
}
```
<p>
Примечание: 
<p>
При возникновении ошибки, помимо возвращенного кода состояния HTTP в поле "message" будет выведено "error", в поле "reason" пояснение, чем вызвана ошибка.

## Тестирование
<p>

Код покрыт модульными тестами на 100%, в том числе под тестирование попадает работа с базой данных.<p>
Для тестирования работы с базой данных используется отдельная тестовая база данных.
При изменении структуры рабочей БД, тесты необходимо исправить.
Тесты запускаются командой `composer test`. <p>
Отчет формируется в папке `/tests/coverage_report`.
